home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / jovept2.arc / MAKE.C < prev    next >
Text File  |  1985-05-30  |  10KB  |  438 lines

  1. /* file make.c */
  2. /* simplified "make" for ms-dos */
  3. /* from usenet posting. */
  4.  
  5. long dateof(), max(), min(), make();
  6. unsigned char *envfind();
  7.  
  8. #include <stdio.h>
  9. #include "bdos.h"
  10.  
  11. #define ERROR -1
  12. #define TRUE 1
  13. #define FALSE 0
  14.  
  15. #define DEFAULT    "MAKEFILE"
  16. #define INMAX    130        /* maximum input line length */
  17.  
  18. #define DEPENDANT    1    /* used in calling getmodified */
  19. #define DEFINED        2
  20.  
  21. struct howrec {
  22.     char *howcom,*howargs;
  23.     struct howrec *nexthow;
  24. };
  25.  
  26. struct deprec {
  27.     char *name;
  28.     struct defnrec *def;
  29.     struct deprec *nextdep;
  30. };
  31.  
  32. struct defnrec {
  33.     char *name;
  34.     int uptodate;
  35.      long modified;
  36.     struct deprec *dependson;
  37.     struct howrec *howto;
  38.     struct defnrec *nextdefn;
  39. };
  40.  
  41. struct dorec {
  42.     char *name;
  43.     struct dorec *nextdo;
  44. };
  45.  
  46. struct defnrec *defnlist;
  47. struct dorec *dolist;
  48.  
  49. int execute;
  50. int stopOnErr;
  51. int madesomething;
  52. int knowhow;
  53. int no_file;
  54.  
  55. main(argc,argv)
  56. int argc;
  57. char *argv[];
  58. {
  59.  
  60.  
  61.     
  62.     no_file = 1;
  63.     set_dta();
  64.  
  65.     init(argc,argv);
  66.  
  67.     /* now fall down the dolist and do them all */
  68.  
  69.     while (dolist != NULL) {
  70.         madesomething = FALSE;
  71.  
  72.         make(dolist->name);
  73.  
  74.         if (!madesomething) {
  75.             if (knowhow) {
  76.                 fprintf(stderr,"Make: '%s' is up to date.",dolist->name);
  77.             } else {
  78.                 fprintf(stderr,
  79.                     "Make: Don't know how to make '%s'.",dolist->name);
  80.                 if (stopOnErr)
  81.                     exit(-1);
  82.             }
  83.         }
  84.         dolist = dolist->nextdo;
  85.     }
  86.  
  87. }
  88.  
  89.  
  90. init(argc,argv)
  91. int argc;
  92. char *argv[];
  93. {
  94.     int i, usedefault;
  95.     dolist = NULL;
  96.     defnlist = NULL;
  97.     usedefault = TRUE;
  98.     execute = TRUE;
  99.     stopOnErr = TRUE;
  100.  
  101.     for (i=1; i < argc; i++) {
  102.         if (argv[i][0] == '-') {    /* option */
  103.             switch (argv[i][1]) {
  104.                 case 'f': case 'F':    /* arg following is a makefile */
  105.                     if (++i < argc) {
  106.                         readmakefile(argv[i]);
  107.                         usedefault = FALSE;
  108.                     } else {
  109.                         fprintf(stderr,"Make: '-f' requires filename");
  110.                         exit(-1);
  111.                     }
  112.                     break;
  113.                 case 'i': case 'I':    /* ignore errors on execution */
  114.                     stopOnErr = FALSE;
  115.                     break;
  116.                 case 'n': case 'N':    /* don't execute commands - just print */
  117.                     execute = FALSE;
  118.                     break;
  119.                 default:
  120.                     fprintf(stderr,"Make: unknown option '%s'.",argv[i]);
  121.             }
  122.         } else {    /* it must be something to make */
  123.             add_do(argv[i]);
  124.             no_file = 0;
  125.         }
  126.     }
  127.     if (usedefault)
  128.         readmakefile(DEFAULT);
  129.  
  130. }
  131.  
  132. long make(s)    /* returns the modified date/time */
  133. char *s;
  134. {
  135.     struct defnrec *defnp;
  136.     struct deprec *depp;
  137.     struct howrec *howp;
  138.     long latest, getmodified(), max();
  139.  
  140.     /* look for the definition */
  141.     defnp = defnlist;
  142.  
  143.     while (defnp != NULL) {
  144.         if (strcmp(defnp->name,s) == 0)
  145.             break;
  146.         defnp = defnp->nextdefn;
  147.     }
  148.  
  149.     if (defnp == NULL) {    /* don't know how to make it */
  150.         knowhow = FALSE;
  151.         latest = getmodified(s,DEFINED);
  152.         if (latest==0) {    /* doesn't exist but don't know how to make */
  153.             fprintf(stderr,"Make: Can't make '%s'.",s);
  154.             exit(-1);
  155.         } else    /* exists - assume it's up to date since we don't know */
  156.             return(latest);
  157.     }
  158.  
  159.     if (defnp->uptodate)
  160.         return(defnp->modified);
  161.  
  162.     /* now make sure everything that it depends on is up to date */
  163.     latest = 0;
  164.     depp = defnp->dependson;
  165.     while (depp != NULL) {
  166.  
  167.         latest = max(make(depp->name),latest);
  168.         depp = depp->nextdep;
  169.     }
  170.  
  171.     knowhow = TRUE;    /* has dependencies therefore we know how */
  172.  
  173.     /* if necessary, execute all of the commands to make it */
  174.     /* if (out of date) || (depends on nothing)             */
  175.     if (latest > defnp->modified || defnp->dependson==NULL) {
  176.         /* make those suckers */
  177.         howp = defnp->howto;
  178.         while (howp != NULL) {
  179. /*            printf("%s %s\n",howp->howcom,howp->howargs); */
  180.             if (execute) {
  181.                 char filename[100];    /* extra space */
  182.                 if (1) {
  183.                     if (execl(howp->howcom,howp->howargs) != 0) {
  184.                         fprintf(stderr,
  185.                         "Make: error from %s",howp->howcom);
  186.                         if (stopOnErr)
  187.                             exit(-1);
  188.                     }
  189.                 } else {
  190.                     fprintf(stderr,"Make: Can't find '%s'.",
  191.                         howp->howcom);
  192.                     if (stopOnErr)
  193.                         exit(-1);
  194.                 }
  195.                 putchar('\n');    /* in case command leaves us dangling */
  196.             }
  197.             howp = howp->nexthow;
  198.         }
  199. /* Only say it`s as recent as it's latest dependent - that way
  200.     if we don't actually have a file for this dependency, it works
  201.     ok
  202. */
  203.         defnp->modified = latest;
  204.         defnp->uptodate = TRUE;
  205.         if (defnp->howto != NULL)    /* we had instructions */
  206.             madesomething = TRUE;
  207.     }
  208.  
  209.     return(defnp->modified);
  210.  
  211. }
  212.  
  213.  
  214. add_do(s)
  215. char *s;
  216. {
  217.     struct dorec *ptr1, *ptr2;
  218.     char *getmem();
  219.  
  220.     ptr1 = getmem(sizeof(struct dorec));
  221.  
  222.     ptr1->name = s;    /* okay since only called with an argv */
  223.     ptr1->nextdo = NULL;
  224.  
  225.     uppercase(ptr1->name);
  226.  
  227.     /* now go down the dolist */
  228.     if (dolist == NULL)
  229.         dolist = ptr1;
  230.     else {
  231.         ptr2 = dolist;
  232.         while (ptr2->nextdo != NULL)
  233.             ptr2 = ptr2->nextdo;
  234.         ptr2->nextdo = ptr1;
  235.     }
  236.  
  237. }
  238.  
  239.  
  240. readmakefile(s)
  241. char *s;
  242. {
  243.     FILE *fil;
  244.  
  245.     int doneline, pos, i, j;
  246.     char inline[INMAX], info[INMAX];
  247.     char *getmem();
  248.     struct defnrec *defnp, *defnp2;
  249.     struct deprec *depp, *depp2;
  250.     struct howrec *howp, *howp2;
  251.  
  252.     if ( (fil = fopen(s,"r")) < 0) {
  253.         fprintf(stderr,"Make: Couldn't open '%s'.",s);
  254.         return;
  255.     }
  256.  
  257.     while (fgets(inline,INMAX,fil) != NULL) {
  258.  
  259.         inline[strlen(inline) - 1] = '\0';
  260.  
  261.         if (inline[0] == '\0')    /* ignore blank lines */
  262.             continue;
  263.  
  264.         if (!isspace(inline[0])) {    /* start of a new definition */
  265.             uppercase(inline);
  266.  
  267.             /* get what we're defining into info */
  268.             if (sscanf(inline,"%s ",info) != 1) {
  269.                 fprintf(stderr,"Make: Can't scan: '%s'.",inline);
  270.                 continue;
  271.             }
  272.  
  273.             /* test for wildcards in file being defined */
  274.             for(i=0;info[i]!='\0';i++)
  275.                 if (s[i]=='?' || s[i]=='*') {
  276.                     fprintf(stderr,"Make: Definition of '%s'.",info);
  277.                     fprintf(stderr,"  contains wildcard.");
  278.                     break;
  279.                 }
  280.  
  281.             /* get a new struct */
  282.             defnp = getmem(sizeof(struct defnrec));
  283.             /* add it to the end of defnlist */
  284.             if (defnlist == NULL)
  285.                 defnlist = defnp;
  286.             else {
  287.                 defnp2 = defnlist;
  288.                 while (defnp2->nextdefn != NULL)
  289.                     defnp2 = defnp2->nextdefn;
  290.                 defnp2->nextdefn = defnp;
  291.             }
  292.             /* initialize it */
  293.  
  294.             defnp->name = getmem(strlen(info)+1);
  295.             strcpy(defnp->name,info);
  296.  
  297.             if(no_file) {
  298.                 add_do(defnp->name);                
  299.                 no_file = 0;
  300.             }
  301.  
  302.             defnp->uptodate = FALSE;    /* actually unknown */
  303.             defnp->modified = getmodified(defnp->name,DEFINED);
  304.             defnp->dependson = NULL;
  305.             defnp->howto = NULL;
  306.             defnp->nextdefn = NULL;
  307.  
  308.             /* now go through all of its dependecies */
  309.             /* first move past the first name */
  310.             pos = 0;
  311.             while (isspace(inline[pos]))
  312.                 pos++;
  313.             while (!isspace(inline[pos]) && inline[pos]!='\0')
  314.                 pos++;
  315.             /* now loop through those suckers */
  316.             doneline = FALSE;
  317.             while (!doneline) {
  318.                 while (isspace(inline[pos]))
  319.                     pos++;
  320.                 if (inline[pos] == '\0') {
  321.                     doneline = TRUE;
  322.                     continue;
  323.                 }
  324.                 for(i = 0; !isspace(inline[pos]) && inline[pos]!='\0'; )
  325.                     info[i++] = inline[pos++];
  326.                 info[i] = '\0';
  327.                 /* get a new struct */
  328.                 depp = getmem(sizeof(struct deprec));
  329.                 /* add it to the end of deplist */
  330.                 if (defnp->dependson == NULL)
  331.                     defnp->dependson = depp;
  332.                 else {
  333.                     depp2 = defnp->dependson;
  334.                     while (depp2->nextdep != NULL)
  335.                         depp2 = depp2->nextdep;
  336.                     depp2->nextdep = depp;
  337.                 }
  338.                 depp->name = getmem(strlen(info)+1);
  339.                 strcpy(depp->name,info);
  340.                 depp->nextdep = NULL;
  341.             }
  342.         } else {    /* a how to line that starts with blank or tab */
  343.             if (defnp == NULL) {
  344.                 fprintf(stderr,"Make: Howto line without a definition.");
  345.                 fprintf(stderr,"Make: '%s'.",inline);
  346.             }
  347.             /* now split the line up into command and args */
  348.             for (pos=0;isspace(inline[pos]); pos++);
  349.                 ;
  350.             for (i=pos; !isspace(inline[i]) && inline[i]!='\0'; i++)
  351.                 ;
  352.             /* if there is something there, allocate mem and copy */
  353.             if (i != pos) {
  354.                 /* get a new struct */
  355.                 howp = getmem(sizeof(struct howrec));
  356.                 /* add it to the end of howlist */
  357.                 if (defnp->howto == NULL)
  358.                     defnp->howto = howp;
  359.                 else {
  360.                     howp2 = defnp->howto;
  361.                     while (howp2->nexthow != NULL)
  362.                         howp2 = howp2->nexthow;
  363.                     howp2->nexthow = howp;
  364.                 }
  365.                 /* copy command filename */
  366.                 howp->howcom = getmem(i-pos+1);
  367.                 for(j=0; pos < i; )
  368.                     howp->howcom[j++] = inline[pos++];
  369.                 howp->howcom[j] = '\0';
  370.                 /* now look for any argumentative part */
  371.                 while (isspace(inline[pos]))
  372.                     pos++;
  373.                 howp->howargs = getmem(strlen(inline)-pos + 1);
  374.                 for(i=0; inline[pos] != '\0'; )
  375.                     howp->howargs[i++] = inline[pos++];
  376.                 howp->howargs[i] = '\0';
  377.                 howp->nexthow = NULL;
  378.             }
  379.         }
  380.     }
  381. }
  382.  
  383.  
  384. uppercase(s)
  385. char *s;
  386. {
  387.     for( ; *s != '\0'; s++)
  388.         *s = toupper(*s);
  389. }
  390.  
  391.  
  392. char *getmem(size)
  393. int size;
  394. {
  395.     char *p;
  396.     if ((p = malloc(size)) == 0) {
  397.         fprintf(stderr,"Make: Ran out of memory.");
  398.         exit(-1);
  399.     }
  400.     return(p);
  401. }
  402.  
  403.  
  404. long getmodified(name,which)
  405. char *name;
  406. int which;
  407. {
  408.     static int save_es, dta_seg, dta_offset;
  409.     long datetime, dateof(), max(), min();
  410.  
  411.     datetime = 0;    /* as old as possible if does not exist */
  412.     set_dta();
  413.     if (find_first(name) == 0) {    /* at least one matching file exists */
  414.         datetime = dateof();
  415.         /* now loop through all the rest of the matching files */
  416.         while (find_next() == 0) {
  417.             if (which == DEPENDANT)
  418.                 datetime = max(datetime, dateof());
  419.             else    /* this is DEFINED */
  420.                 datetime = min(datetime, dateof());
  421.         }
  422.     } else    /* doesn't exist */
  423.         datetime = 0;    /* as old as possible */
  424.     return(datetime);
  425. }
  426.  
  427. long max(a,b)
  428. long a,b;
  429. {
  430.     return(a>b ? a : b);
  431. }
  432.  
  433. long min(a,b)
  434. long a,b;
  435. {
  436.     return(a>b ? b : a);
  437. }
  438.